import datetime

import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas as pd

# 设置字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 数据准备
data = {
    '任务': ['制定计划', '方案设计', '资源调配', '第一阶段', '第二阶段', '第三阶段', '项目总结'],
    '开始日期': ['2022-03-01', '2022-03-13', '2022-03-22', '2022-04-02', '2022-04-16', '2022-05-11', '2022-05-26'],
    '项目天数': [11, 8, 10, 13, 24, 14, 7],
    '完成度': [51, 32, 21, 85, 36, 68, 68],
    '进行天数': [5.61, 2.56, 2.1, 11.05, 8.64, 9.52, 4.76],
    '结束日期': ['2022-03-12', '2022-03-21', '2022-04-01', '2022-04-15', '2022-05-10', '2022-05-25', '2022-06-02']
}

df = pd.DataFrame(data)
bar_height = 0.4  # 调整此值以改变条形宽度

# 将日期转换为datetime格式
df['开始日期'] = pd.to_datetime(df['开始日期'])
df['结束日期'] = pd.to_datetime(df['结束日期'])

# 绘图
fig, ax = plt.subplots(figsize=(12, 8))

# 设置背景颜色
fig.patch.set_facecolor('#1A1E43')
ax.set_facecolor('#1A1E43')

# 任务条
for i in range(len(df)):
    start_date = df['开始日期'][i]
    project_days = df['项目天数'][i]
    end_date = df['结束日期'][i]
    completion = df['完成度'][i] / 100.0

    # 总任务条
    ax.barh(df['任务'][i],
            project_days,
            left=start_date,
            color='skyblue', edgecolor='black', height=bar_height)

    # 完成度条
    ax.barh(df['任务'][i],
            df['进行天数'][i],
            left=start_date,
            color='dodgerblue', edgecolor='black', height=bar_height)

    # 完成度文本
    ax.text(start_date + datetime.timedelta(days=project_days * completion / 2),
            i,
            f'{df["完成度"][i]}%',
            ha='center',
            va='center',
            color='white',
            fontweight='bold')

# 设置日期格式
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
ax.xaxis.set_major_locator(mdates.WeekdayLocator(interval=2))

# 将日期刻度和标签移到上面
ax.xaxis.set_ticks_position('top')
ax.xaxis.set_label_position('top')

# 其他设置
ax.set_title('2022化妆品类目采购项目进度', fontsize=30, color='white', pad=60, weight='bold', loc='center')
ax.grid(axis='x', linestyle='--', linewidth=0.5, color='gray')

# 反转Y轴使其从上到下按任务顺序显示
ax.invert_yaxis()

# 设置坐标轴颜色
ax.tick_params(axis='x', colors='white', labelsize=15)  # 设置x轴刻度标签字体大小和颜色
ax.tick_params(axis='y', colors='white', labelsize=15)  # 设置y轴刻度标签字体大小和颜色

# 隐藏坐标轴，保留刻度
for position in ['left', 'right', 'top', 'bottom']:
    ax.spines[position].set_color('none')

plt.tight_layout()
plt.show()
